package cn.wizzer.app.crown.modules.services.impl.pl.bk;

import cn.wizzer.app.crown.commons.util.DateUtil;
import cn.wizzer.app.crown.commons.websocket.action.hg.SimplexPlayWayAction;
import cn.wizzer.app.crown.modules.models.CrownConfig;
import cn.wizzer.app.crown.modules.models.CrownMatch;
import cn.wizzer.app.crown.modules.models.CrownSubResult;
import cn.wizzer.app.crown.modules.models.caches.CrownMatchSimplex;
import cn.wizzer.app.crown.modules.models.constant.CrownConstant;
import cn.wizzer.app.crown.modules.models.constant.CrownPattern;
import cn.wizzer.app.crown.modules.models.constant.CrownRedisConstant;
import cn.wizzer.app.crown.modules.models.enums.MatchTypeEnum;
import cn.wizzer.app.crown.modules.models.enums.PlayWayEnum;
import cn.wizzer.app.crown.modules.models.enums.SubResultEnum;
import cn.wizzer.app.crown.modules.services.CrownConfigService;
import cn.wizzer.app.crown.modules.services.CrownMatchService;
import cn.wizzer.app.crown.modules.services.CrownSubResultService;
import cn.wizzer.app.crown.modules.services.pl.bk.BKRResolverService;
import cn.wizzer.app.match.modules.models.constant.Fields;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.util.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// 篮球单式今日/早盘/滚球爬虫、数据解析入库。
@IocBean(args = {"refer:dao"})
@Service(interfaceClass = BKRResolverService.class)
public class BKRResolverServiceImpl extends BaseServiceImpl<CrownMatch> implements BKRResolverService {
    private static final Log log = Logs.get();

    public BKRResolverServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private RedisService redisService;
    @Inject
    private CrownMatchService matchService;
    @Inject
    private CrownSubResultService subResultService;
    @Inject
    @Reference(retries = 0, timeout = 500000)
    private CrownConfigService crownConfigService;


    private void crawler(String dateType, Integer pageNo, CrownConfig crownConfig) {
        new PageAction() {
            @Override
            public void handle(List<JSONArray> list, String date, String dateType) {
                Set<String> leagues = new HashSet<>();
                Deque<CrownMatch> queue = new LinkedList<>();

                // 缓存league信息
                // String leagueKey = "CROWN_FOOTBALL_R_FUTURE_LEAGUE";
                String leagueKey = Fields.PREFIX_CROWN + MatchTypeEnum.BASKETBALL + Fields.KEY_JOIN + PlayWayEnum.R + Fields.KEY_JOIN + dateType.toUpperCase() + Fields.SUFFIX_LEAGUE;
                // 缓存match信息
                // String matchKey = "CROWN_FOOTBALL_R_FUTURE_MATCH";
                String matchKey = Fields.PREFIX_CROWN + MatchTypeEnum.BASKETBALL + Fields.KEY_JOIN + PlayWayEnum.R + Fields.KEY_JOIN + dateType.toUpperCase() + Fields.SUFFIX_MATCH;

                // browser future
                if (!CrownConstant.RUNNING.equals(dateType)) {
                    list.forEach(gm -> {
                        String[] dateTime = gm.getString(1).toLowerCase().split("<br>");
                        int dateTimeLength = dateTime.length;
                        CrownMatch match = new CrownMatch();
                        match.setStage(dateType);
                        match.setType(MatchTypeEnum.BASKETBALL);
                        if (dateTimeLength == 3) {
                            match.setStart(dateTime[2]);
                            match.setHaveRoll(true);
                        } else {
                            match.setStart("");
                            match.setHaveRoll(false);
                        }
                        if (dateType.equals(CrownConstant.FUTURE)) {
                            match.setDateTime(DateUtil.parseDate(date.substring(0, 5) + dateTime[0] + " " + (dateTimeLength >= 2 ? dateTime[1] + "m" : ""), DateUtil.DATE_FORMAT_PATTERN.Y_M_D_H_M_A.PATTERN));
                        } else {
                            match.setDateTime(DateUtil.parseDate(date + " " + (dateTimeLength >= 2 ? dateTime[1] + "m" : ""), DateUtil.DATE_FORMAT_PATTERN.Y_M_D_H_M_A.PATTERN));
                        }
                        match.setLeague(gm.getString(2));
                        String mbTeam = gm.getString(5).trim();
                        mbTeam = CrownPattern.HTML_PATTERN.matcher(mbTeam).replaceAll("");
                        if (mbTeam.contains("[中]")) {
                            // 把[中]替换为空
                            mbTeam = mbTeam.replace("[中]", "").trim();
                            match.setHaveHome(false);
                        } else {
                            match.setHaveHome(true);
                        }
                        match.setMbTeam(mbTeam.trim());
                        // 去除客队名称HTML标签
                        String tgTeam = gm.getString(6).trim();
                        tgTeam = CrownPattern.HTML_PATTERN.matcher(tgTeam).replaceAll("");
                        match.setTgTeam(tgTeam);
                        match.setStrong(gm.getString(7));
                        match.setIsHalfGone(false);

                        CrownMatch old = matchService.queryByTeamInfo(match.getLeague(), match.getMbTeam(), match.getTgTeam(), match.getDateTime());
                        if (old != null) {
                            match.setId(old.getId());
                            match.setMid(old.getMid());
                        }

                        String redisKey = CrownRedisConstant.SIMPLEX + match.getId();

                        //接口第一条数据，若此赛事数据为第一次出现则重新拼接redisKey
                        if (queue.size() == 0) {
                            // 爬取赛事的mid
                            match.setMid(gm.getString(0));
                            queue.add(match);
                            redisKey = saveMatchInfo(match, matchKey, leagues, redisKey, CrownRedisConstant.TIME_OUT_180_S);
                        }
                        //数据1+n条
                        else {
                            //玩法其他情况处理
                            CrownMatch last = queue.getLast();
                            if (last.getId().equals(match.getId())) {
                                queue.add(match);
                            }
                            //说明此处已改为其他赛事（非上一赛事其他玩法）
                            else {
                                queue.clear();
                                // 爬取赛事的mid
                                match.setMid(gm.getString(0));
                                queue.add(match);
                                //此数据可能是新出现的赛事（数据库中尚未保存）
                                redisKey = saveMatchInfo(match, matchKey, leagues, redisKey, CrownRedisConstant.TIME_OUT_180_S);
                            }
                        }
                        // set plays
                        CrownMatchSimplex simplex = new CrownMatchSimplex();
                        simplex.setMatchType(MatchTypeEnum.BASKETBALL);
                        simplex.setPlayWay(PlayWayEnum.R);
                        simplex.setCrownMatchId(match.getId());
                        simplex.setNo2(queue.size());
                        // 主队独赢赔率
                        simplex.setNo1(1);
                        simplex.setNo3(1);
                        simplex.setOdds(gm.getBigDecimal(15));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);
                        //客队独赢赔率
                        simplex.setNo3(2);
                        simplex.setOdds(gm.getBigDecimal(16));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);
                        // 主队让球赔率
                        simplex.setNo1(2);
                        simplex.setNo3(1);
                        // 让球系数
                        simplex.setCoeNum((gm.getString(7).equals("H") ? "" : "-") + gm.getString(8));
                        simplex.setOdds(gm.getBigDecimal(9));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);
                        // 客队让球赔率
                        simplex.setNo3(2);
                        simplex.setCoeNum((gm.getString(7).equals("C") ? "" : "-") + gm.getString(8));
                        simplex.setOdds(gm.getBigDecimal(10));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);
                        // ‘大’赔率
                        simplex.setNo1(3);
                        simplex.setNo3(1);
                        // ‘大’系数
                        String o = gm.getString(11).replace("O", "");
                        simplex.setCoeNum(Strings.isEmpty(o) ? null : o);
                        simplex.setCoeWord("大");
                        simplex.setOdds(gm.getBigDecimal(14));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);
                        // ‘小’赔率
                        simplex.setNo3(2);
                        // ‘小’系数
                        String u = gm.getString(12).replace("U", "");
                        simplex.setCoeNum(Strings.isEmpty(u) ? null : u);
                        simplex.setCoeWord("小");
                        simplex.setOdds(gm.getBigDecimal(13));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);

                        // 主队球队得分‘大’
                        simplex.setNo1(4);
                        simplex.setNo3(1);
                        simplex.setCoeWord("大");
                        String o1 = gm.getString(22).replace("O", "");
                        simplex.setCoeNum(Strings.isEmpty(o1) ? null : o1);
                        simplex.setOdds(gm.getBigDecimal(24));// '球队得分大小'索引位置与'大小'索引位置不一样。
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);

                        // 主队球队得分‘小’
                        simplex.setNo1(5);
                        simplex.setCoeWord("小");
                        String u1 = gm.getString(23).replace("U", "");
                        simplex.setCoeNum(Strings.isEmpty(u1) ? null : u1);
                        simplex.setOdds(gm.getBigDecimal(25));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);


                        // 客队球队得分‘大’
                        simplex.setNo1(4);
                        simplex.setNo3(2);
                        simplex.setCoeWord("大");
                        String o2 = gm.getString(26).replace("O", "");
                        simplex.setCoeNum(Strings.isEmpty(o2) ? null : o2);
                        simplex.setOdds(gm.getBigDecimal(28));// '球队得分大小'索引位置与'大小'索引位置不一样。
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);

                        // 客队球队得分‘小’
                        simplex.setNo1(5);
                        simplex.setCoeWord("小");
                        String u2 = gm.getString(27).replace("U", "");
                        simplex.setCoeNum(Strings.isEmpty(u2) ? null : u2);
                        simplex.setOdds(gm.getBigDecimal(29));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_180_S);
                        // 推送整场比赛信息
                        SimplexPlayWayAction.instance().push(match.getId(), matchService.composeMatch(CrownRedisConstant.SIMPLEX, match));
                    });
                    cacheLeague(leagues, leagueKey, matchKey, CrownRedisConstant.TIME_OUT_180_S);
                } else {
                    // running
                    list.forEach(gm -> {
                        // 赛事信息入库
                        String[] dateTime = gm.getString(47).toLowerCase().split("<br>");
                        String startTime = gm.getString(48).split("\\^")[1] + "m";
                        CrownMatch match = new CrownMatch();
                        match.setStage(dateType);
                        match.setType(MatchTypeEnum.BASKETBALL);
                        match.setStart(startTime);
                        match.setHaveRoll(true);
                        match.setDateTime(DateUtil.parseDate(date + " " + dateTime[1] + "m", DateUtil.DATE_FORMAT_PATTERN.Y_M_D_H_M_A.PATTERN));
                        match.setLeague(gm.getString(2));
                        String mbTeam = gm.getString(5).trim();
                        mbTeam = CrownPattern.HTML_PATTERN.matcher(mbTeam).replaceAll("");
                        if (mbTeam.contains("[中]")) {
                            // 把[中]替换为空
                            mbTeam = mbTeam.replace("[中]", "").trim();
                            match.setHaveHome(false);
                        } else {
                            match.setHaveHome(true);
                        }
                        match.setMbTeam(mbTeam.trim());
                        // 去除客队名称HTML标签
                        String tgTeam = gm.getString(6).trim();
                        tgTeam = CrownPattern.HTML_PATTERN.matcher(tgTeam).replaceAll("");
                        match.setTgTeam(tgTeam);
                        match.setStrong(gm.getString(7));

                        CrownMatch old = matchService.queryByTeamInfo(match.getLeague(), match.getMbTeam(), match.getTgTeam(), match.getDateTime());
                        if (old != null) {
                            match.setId(old.getId());
                            match.setMid(old.getMid());
                            match.setVersion(old.getVersion());
                            match.setIsHalfGone(old.getIsHalfGone());
                            match.setMbInBallHf(old.getMbInBallHf());
                            match.setTgInBallHf(old.getTgInBallHf());
                        } else {
                            match.setIsHalfGone(false);
                        }

                        // 设置滚球中的时间和比分
                        if (Strings.isNotBlank(gm.getString(52))) {
                            // 判断'半场'
                            if ("HT".equals(gm.getString(52))) {
                                match.setProcess("半场");
                                match.setMbInBallHf(gm.getString(53));
                                match.setTgInBallHf(gm.getString(54));
                                match.setIsHalfGone(true);
                                match.setVersion(0);
                            } else {
                                // 第几节
                                String process = gm.getString(52).replace("Q", "第") + "节 ";
                                // 计算进行时间(爬到的值有的是小数，有的是整数，所以统一getDouble再转int)
                                String runningMinute = String.format("%02d", gm.getDouble(56).intValue() / 60);
                                String runningSecond = String.format("%02d", gm.getDouble(56).intValue() % 60);
                                String runningTime = runningMinute + ":" + runningSecond;
                                match.setProcess(process + runningTime);
                            }
                            // 比分 不存库只存redis用
                            match.setScore(gm.getString(53) + "-" + gm.getString(54));
                        }

                        String redisKey = CrownRedisConstant.SIMPLEX + match.getId();

                        // 计算no2
                        if (queue.size() == 0) {
                            // 爬取赛事的mid(只有情况1的mid才能存，因为情况2、3的mid各不一样)
                            match.setMid(gm.getString(0));
                            queue.add(match);
                            redisKey = saveMatchInfo(match, matchKey, leagues, redisKey, CrownRedisConstant.TIME_OUT_15_S);
                        } else {
                            CrownMatch last = queue.getLast();
                            if (last.getId().equals(match.getId())) {
                                queue.add(match);
                            } else {
                                queue.clear();
                                // 爬取赛事的mid(只有情况1的mid才能存，因为情况2、3的mid各不一样)
                                match.setMid(gm.getString(0));
                                queue.add(match);
                                redisKey = saveMatchInfo(match, matchKey, leagues, redisKey, CrownRedisConstant.TIME_OUT_15_S);
                            }
                        }
                        // 处理玩法信息入Redis
                        CrownMatchSimplex simplex = new CrownMatchSimplex();
                        simplex.setMatchType(MatchTypeEnum.BASKETBALL);
                        simplex.setPlayWay(PlayWayEnum.R);
                        simplex.setCrownMatchId(match.getId());
                        //玩法情景n
                        simplex.setNo2(queue.size());
                        // 主队独赢赔率
                        simplex.setNo1(1);
                        simplex.setNo3(1);
                        simplex.setOdds(gm.getBigDecimal(15));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);
                        //客队独赢赔率
                        simplex.setNo3(2);
                        simplex.setOdds(gm.getBigDecimal(16));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);
                        // 主队让球赔率
                        simplex.setNo1(2);
                        simplex.setNo3(1);
                        // 让球系数
                        simplex.setCoeNum((gm.getString(7).equals("H") ? "" : "-") + gm.getString(8));
                        simplex.setOdds(gm.getBigDecimal(9));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);
                        // 客队让球赔率
                        simplex.setNo3(2);
                        simplex.setCoeNum((gm.getString(7).equals("C") ? "" : "-") + gm.getString(8));
                        simplex.setOdds(gm.getBigDecimal(10));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);
                        // ‘大’赔率
                        simplex.setNo1(3);
                        simplex.setNo3(1);
                        // ‘大’系数
                        String o1 = gm.getString(11).replace("O", "");
                        simplex.setCoeNum(Strings.isEmpty(o1) ? null : o1);
                        simplex.setCoeWord("大");
                        simplex.setOdds(gm.getBigDecimal(14));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);
                        // ‘小’赔率
                        simplex.setNo3(2);
                        // ‘小’系数
                        String u = gm.getString(12).replace("U", "");
                        simplex.setCoeNum(Strings.isEmpty(u) ? null : u);
                        simplex.setCoeWord("小");
                        simplex.setOdds(gm.getBigDecimal(13));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);


                        // 主队球队得分‘大’
                        simplex.setNo1(4);
                        simplex.setNo3(1);
                        simplex.setCoeWord("大");
                        String o = gm.getString(35).replace("O", "");
                        simplex.setCoeNum(Strings.isEmpty(o) ? null : o);
                        simplex.setOdds(gm.getBigDecimal(37));// '球队得分大小'索引位置与'大小'索引位置不一样。
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);

                        // 主队球队得分‘小’
                        simplex.setNo1(5);
                        simplex.setCoeWord("小");
                        String u1 = gm.getString(36).replace("U", "");
                        simplex.setCoeNum(Strings.isEmpty(u1) ? null : u1);
                        simplex.setOdds(gm.getBigDecimal(38));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);


                        // 客队球队得分‘大’
                        simplex.setNo1(4);
                        simplex.setNo3(2);
                        simplex.setCoeWord("大");
                        String o2 = gm.getString(39).replace("O", "");
                        simplex.setCoeNum(Strings.isEmpty(o2) ? null : o2);
                        simplex.setOdds(gm.getBigDecimal(41));// '球队得分大小'索引位置与'大小'索引位置不一样。
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);

                        // 客队球队得分‘小’
                        simplex.setNo1(5);
                        simplex.setCoeWord("小");
                        String u2 = gm.getString(40).replace("U", "");
                        simplex.setCoeNum(Strings.isEmpty(u2) ? null : u2);
                        simplex.setOdds(gm.getBigDecimal(42));
                        compose(redisKey, simplex, CrownRedisConstant.TIME_OUT_15_S);

                        // 推送整场比赛信息
                        SimplexPlayWayAction.instance().push(match.getId(), matchService.composeMatch(CrownRedisConstant.SIMPLEX, match));
                    });
                    cacheLeague(leagues, leagueKey, matchKey, CrownRedisConstant.TIME_OUT_15_S);
                }

            }

            private void cacheLeague(Set<String> leagues, String leagueKey, String matchKey, int timeOut) {
                List<String> lrange = redisService.lrange(leagueKey, 0, -1);
                leagues.addAll(lrange);
                //缓存league信息
                redisService.del(leagueKey);
                leagues.forEach(league -> redisService.rpush(leagueKey, league));

                //设置缓存有效时长
                redisService.expire(leagueKey, timeOut);
            }

            @Aop(TransAop.REPEATABLE_READ)
            private String saveMatchInfo(CrownMatch match, String matchKey, Set<String> leagues, String redisKey, int timeOut) {
                //新出现的赛事则执行插入无需清理旧数据
                if (match.getId() != null) {
                    // 防止玩法重复插入
                    redisService.del(redisKey);
                    matchService.update(match);
                } else {
                    match = matchService.insert(match);
                    redisKey = CrownRedisConstant.SIMPLEX + match.getId();
                }
                // 半场赛果入库
                if (match.getIsHalfGone()) {
                    CrownSubResult oldSubResult = subResultService.fetch(Cnd.where("tag", "=", "NO5")
                            .and("match_id", "=", match.getId()));
                    if (null == oldSubResult) {
                        CrownSubResult subResult = new CrownSubResult();
                        subResult.setMatchId(match.getId());
                        subResult.setGameType(match.getType());
                        subResult.setType(SubResultEnum.GOALS_NUM);
                        subResult.setTag("NO5");
                        subResult.setResultH(match.getMbInBallHf());
                        subResult.setResultC(match.getTgInBallHf());
                        subResult.setRemark("上半场");
                        subResult.setVersion(match.getVersion());
                        subResultService.insertOrUpdate(subResult);
                    }
                }
                leagues.add(match.getLeague());
                // 存入redis并设置过期时间
                redisService.setex(matchKey + ":" + match.getId(), timeOut, JSONUtil.toJSONString(match));

                return redisKey;
            }
        }.page(dateType, pageNo, crownConfig);
    }

    /**
     * 组装单个比赛信息，推送时直接使用
     *
     * @param redisKey
     * @param simplex
     * @param timeOut
     */
    private void compose(String redisKey, CrownMatchSimplex simplex, Integer timeOut) {
        // 具体玩法信息存入redis，并设置过期时间
        redisService.setex(redisKey + ":" + simplex.getNo1() + ":" + simplex.getNo2() + ":" + simplex.getNo3(),
                timeOut,
                JSONObject.toJSONString(simplex));
    }

    @Override
    public void future(CrownConfig crownConfig) {
        crawler(CrownConstant.FUTURE, 0, crownConfig);
    }

    @Override
    public void browse(CrownConfig crownConfig) {
        crawler(CrownConstant.BROWSE, 0, crownConfig);
    }

    @Override
    public void running(CrownConfig crownConfig) {
        crawler(CrownConstant.RUNNING, 0, crownConfig);
    }


    public abstract class PageAction {
        public abstract void handle(List<JSONArray> list, String date, String dateType);

        List<JSONArray> list = new ArrayList<>();
        // 今日、早盘数据中空白的索引
        int[] eleIdxs = new int[]{9, 10, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29};
        // 滚球数据中空白的索引
        int[] runIdxs = new int[]{9, 10, 13, 14, 37, 38, 41, 42};
        String rtype = "r_main";

        public void page(String type, Integer pageNo, CrownConfig config) {
            String urlParam = type;
            if (CrownConstant.RUNNING.equals(type)) {
                eleIdxs = runIdxs;
                urlParam = CrownConstant.BROWSE;// 滚球url参数也是BK_browse，不是BK_running。如果直接赋值给type，传参handle方法有bug。
                rtype = "re_main";
            }
            while (true) {
                log.info("获取篮球单式玩法实时数据");
                String tailUrl = String.format("/app/member/BK_%s/body_var.php?uid=%s&rtype=%s&langx=%s&mtype=3" +
                                "&page_no=%d&g_date=ALL&league_id=&hot_game=&isie11=%%27N%%27",

                        urlParam, config.getUid(), rtype, CrownConstant.LANGX, pageNo);

                String body = crownConfigService.getCrownData(tailUrl, config, CrownConstant.RE_TRY_TIMES);

                // 检测账号被登出
                if (crownConfigService.checkLogout(body, config)) {
                    // 重试登录(包括重试三次、自动请求新地址)
//                    crownConfigService.loginHg(config);
//                    // 如果还是登录失败 直接return结束 避免死循环
//                    if (config.isLogout()) {
//                        return;
//                    }
//                    // 登录成功则continue重新去请求
//                    continue;
                    return;
                }

                // body是空，监测到皇冠维护都return
                if (Strings.isBlank(body)) {
                    log.error("爬取篮球单式失败，body为空");
                    return;
                } else if (crownConfigService.checkMaintain(body, config)) {
                    return;
                }

                // 解析数据
                // 页数
                Matcher m = CrownPattern.TOTAL_PAGE_NUM_PATTERN.matcher(body);
                Integer pg = 0;
                if (m.find()) {
                    pg = Integer.valueOf(m.group(0).replace(";", "").replace("t_page=", ""));
                    log.info("获取总页数：" + pg);
                } else {
                    log.error("爬取不到页数,即将开启维护.URL:" + tailUrl + "===body:" + body);
                    // 如果爬取不到总页数,调用监测接口
                    crownConfigService.checkMaintain(CrownConstant.MAINTAIN_INFO_SHORT, config);
                }
                m = CrownPattern.SYSTEM_DATE_PATTERN.matcher(body);
                String date = null;
                if (m.find()) {
                    date = m.group(0).replace(";", "").replace("top.today_gmt = ", "").replace("'", "");
                    log.info("获取系统日期：" + date);
                }
                // body_var 列表信息
                m = CrownPattern.G_METHOD_DATA_PATTERN.matcher(body);
                Pattern fr;
                Matcher fm;
                while (m.find()) {
                    String v = m.group();
                    v = v.substring(2, v.length() - 2);
                    JSONArray ds = JSONArray.parseArray(v);
                    fr = Pattern.compile("gm\\[\\'" + ds.get(0) + "(.*?)\\'\\];");
                    fm = fr.matcher(body);
                    String gms = "";
                    if (fm.find()) {
                        gms = fm.group();
                    }
                    JSONArray gm;
                    if (Strings.isNotBlank(gms)) {
                        gm = JSONArray.parseArray(gms.substring(7 + ds.get(0).toString().length(), gms.length() - 1));
                        gm.add(0, ds.get(0));
                        ds.remove(0);
                        gm.addAll(ds);
                    } else {
                        gm = ds;
                    }
                    // eleIndex 这些位置有些值为null,需要给填上默认值0
                    for (int i = 0; i < eleIdxs.length; i++) {
                        if (Strings.isEmpty(gm.getString(eleIdxs[i]))) {
                            gm.remove(eleIdxs[i]);
                            gm.add(eleIdxs[i], 0);
                        }
                    }
                    list.add(gm);
                }

                if (pg <= ++pageNo) {
                    log.info("爬取成功，（bkr）数据条数bkr->pageNo:" + pageNo + ",pageSize:" + list.size());
                    handle(list, date, type);
                    return;
                }
            }
        }
    }
}
